package ig.metrica.riesgo;

import java.rmi.RemoteException;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Properties;
import javax.ejb.FinderException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import ig.finanzas.Banda;
import ig.finanzas.ContratoPK;
import ig.finanzas.ContratoSimple;
import ig.finanzas.ContratoSimpleHome;
import ig.finanzas.EspeciePK;
import ig.finanzas.Flujo;
import ig.finanzas.ManejadorBandas;
import ig.finanzas.ManejadorFlujos;
import ig.finanzas.Moneda;
import ig.finanzas.MonedaHome;
import ig.finanzas.MonedaPK;
import ig.finanzas.PosicionAccion;
import ig.finanzas.PosicionAccionHome;
import ig.finanzas.PosicionEspecie;
import ig.finanzas.PosicionEspecieHome;
import ig.finanzas.Tasa;
import ig.finanzas.TasaHome;
import ig.finanzas.TasaPK;
import ig.finanzas.riesgo.FactorRiesgoMatrizCorrelacion;
import ig.finanzas.riesgo.FactorRiesgoPersonal;
import ig.metrica.TasaFactorDescuento;
import ig.metrica.ejb.bean.Productos;
import ig.metrica.ejb.html.GenerarHTML;
import ig.util.ConexionServer;
import ig.util.ejb.IGLlaveInt;
import ig.util.ejb.IGSessionBean;
import ig.util.excepciones.DatoInvalidoExcepcion;
import ig.util.excepciones.LogicaExcepcion;
import java.util.ArrayList;

public class CalculoRiesgoBeanMaCor_051 extends IGSessionBean implements CalculoRiesgoBussines {

    private GenerarHTML generarHTML = null;
    private Properties prop = null;
    private Hashtable cambioesperadoMonedas = new Hashtable();
    private MonedaHome monedaHome = null;
    private InitialContext _ctx = null;
    private TasaHome tasaHome = null;
    private Collection<ZonaDTO> collection = new ArrayList();
    private Collection factores = null;
    private boolean fechaInicioCerrada = false;

    public CalculoRiesgoBeanMaCor_051() {
    }

    {
        prop = new Properties();
        prop.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
        String Sockec = new ConexionServer().getSocketServer();
        prop.put(Context.PROVIDER_URL, Sockec);
    }

    public void setGenerarHTML(GenerarHTML generarHTML) {
        this.generarHTML = generarHTML;
    }

    public void ejbCreate() {
    }

    private Moneda getMoneda(MonedaPK monedaPK) throws NamingException, FinderException {

        try {
            if (monedaHome == null) {
                if (_ctx == null) {
                    _ctx = new InitialContext(prop);
                }
                monedaHome = (MonedaHome) _ctx.lookup("ig.finanzas.Moneda");
            }
            return monedaHome.findByPrimaryKey(monedaPK);
        } catch (RemoteException e) {
            System.out.println("ERROR:" + e.toString());
        }
        return null;

    }

    private Tasa getTasa(TasaPK tasaPK) throws NamingException, FinderException {
        try {
            if (tasaHome == null) {
                if (_ctx == null) {
                    _ctx = new InitialContext(prop);
                }
                tasaHome = (TasaHome) _ctx.lookup("ig.finanzas.Tasa");
            }
            return tasaHome.findByPrimaryKey(tasaPK);
        } catch (RemoteException e) {
            System.out.println("ERROR:" + e.toString());
        }
        return null;
    }

    /**
     *
     * @param fecha
     * @param confPeriodos
     * @param numdias
     * @param relacionProductosFactores
     * @param relacionEspeciesFactores
     * @param relacionMonedasFactores
     * @throws DatoInvalidoExcepcion Si alguno de los parametros del metodo es nulo,
     * o si se especifico un factor tipo tasa para las acciones o uno tipo precio para los contratos simples.
     * o si alguno de los datos de la configuracion de los periodos de una banda es 0,
     * o si un dato es menor a su inmediatamente anterior.
     * @throws LogicaExcepcion Si no se definio Factor de Riesgo para algun producto, alguna especie o
     * para alguna moneda, si alguna de las formas de calculo del cambio esperado no permite obtener el valor, si no hay suficientes
     * valores en la serie, si la informacion hallada no alcanza a ser una muestra estadisticamente representativa,
     * o si la serie no permite el calculo utilizando diferencias logaritmicas.
     * O si al querer calcular el var de un contrato usando tasas este no tiene flujos para efectuar la operacion.
     * @throws NamingException Si se presento un error con JNDI.
     * @throws SQLException Si no se pueden encontrar los objetos en el servidor de aplicaciones.
     * @throws FinderException Si no se pueden encontrar los objetos en el servidor de aplicaciones.
     */
    public void efectuarCalculo(
            Date fecha,
            ManejadorBandas bandas,
            Hashtable relacionProductosFactores,
            Hashtable relacionEspeciesFactores,
            Hashtable relacionMonedasFactores) throws DatoInvalidoExcepcion, LogicaExcepcion, NamingException, SQLException, FinderException {

        if (fecha == null) {
            generarHTML.println("La fecha especificada es nula.");
            throw new DatoInvalidoExcepcion("La fecha especificada es nula.");
        }
        if (relacionProductosFactores == null && relacionEspeciesFactores == null) {
            generarHTML.println("La relacion entre especies/productos y factores de riesgo es nula.");
            throw new DatoInvalidoExcepcion("La relacion entre especies y factores de riesgo es nula.");
        }
        if (relacionMonedasFactores == null) {
            generarHTML.println("La relacion entre monedas y factores de reisgo es nula.");
            throw new DatoInvalidoExcepcion("La relacion entre monedas y factores de reisgo es nula.");
        }

        cambioesperadoMonedas = new Hashtable();
        PreparedStatement pstmt4_ = null;
        //Productos productos = null;
        try {
            conn = getConexion("METRICADB");
            pstmt1 = conn.prepareStatement("INSERT INTO VARCONTRATOSPRECIO VALUES(?, ?, ?, ?)");
            pstmt2 = conn.prepareStatement("INSERT INTO VARCONTRATOSTASA VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
            pstmt3 = conn.prepareStatement("INSERT INTO CAMBIOESPERADOMONEDAS VALUES(?, ?)");
            pstmt4 = conn.prepareStatement("UPDATE CONTRATOS SET VAR1=?, VAR2=?, VAR3=? WHERE ID=?");

            //Calculo para posiciones Acciones
            this.efectuarCalculoParaPosicionesAcciones(fecha, relacionProductosFactores, relacionEspeciesFactores, relacionMonedasFactores);

            //int anterior = 0;
            //ManejadorBandas bandas = ManejadorBandas.crearBandas(fecha, confPeriodos);
            //int ahora = bandas.getColeccionBandas().size();
            /*if (anterior != ahora) {
            anterior = ahora;
            //generarHTML.println((new StringBuilder()).append("Procesando :").append(anterior).append(" Bandas").toString());
            }*/
            pstmt4_ = conn.prepareStatement("INSERT INTO BANDASVAR VALUES(?,?,?) ");
            int contador = 0;
            Banda banda;
            for (Iterator i = bandas.getColeccionBandas().iterator(); i.hasNext(); banda.setIdInterna(contador)) {
                banda = (Banda) i.next();
                contador++;
                pstmt4_.setInt(1, contador);
                pstmt4_.setDate(2, new java.sql.Date(banda.getFechaInicio().getTime()));
                if (banda.getFechaFin() != null) {
                    pstmt4_.setDate(3, new java.sql.Date(banda.getFechaFin().getTime()));
                } else {
                    pstmt4_.setNull(3, java.sql.Types.NULL);
                }
                pstmt4_.executeUpdate();
            }

            //Inicia contrato simple
            this.efectuarCalculoContratosSimples(fecha, relacionProductosFactores, relacionEspeciesFactores, relacionMonedasFactores, bandas);

            //Inicia POsiciones Especie
            this.efectuarCalculoPosicionesEspecies(fecha, relacionProductosFactores, relacionEspeciesFactores, relacionMonedasFactores, bandas);


            for (Iterator i = cambioesperadoMonedas.keySet().iterator(); i.hasNext(); pstmt3.executeUpdate()) {
                MonedaPK monedaPK = (MonedaPK) i.next();
                pstmt3.setLong(1, monedaPK.getIdInterna());
                pstmt3.setDouble(2, ((Double) cambioesperadoMonedas.get(monedaPK)).doubleValue());
            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new DatoInvalidoExcepcion(e.toString());
        } finally {
            try {
                pstmt1.close();
            } catch (Exception e) {
            }
            try {
                pstmt2.close();
            } catch (Exception e) {
            }
            try {
                pstmt3.close();
            } catch (Exception e) {
            }
            try {
                pstmt4.close();
            } catch (Exception e) {
            }
            try {
                pstmt4_.close();
            } catch (Exception e) {
            }
            try {
                conn.close();
            } catch (Exception e) {
            }
//            if (productos != null) {
//                productos.Finalizar();
//            }
        }
    }

    public void efectuarCalculoParaPosicionesAcciones(
            Date fecha,
            Hashtable relacionProductosFactores,
            Hashtable relacionEspeciesFactores,
            Hashtable relacionMonedasFactores)

            throws DatoInvalidoExcepcion, LogicaExcepcion, NamingException, SQLException, FinderException {
        try {
            InitialContext ctx_ = new InitialContext(prop);
            PosicionAccionHome home3 = (PosicionAccionHome) ctx_.lookup("ig.finanzas.PosicionAccion");
            Collection contratos = home3.findAll();
            Iterator i = contratos.iterator();
            //generarHTML.println((new StringBuilder()).append("Procesando :").append(contratos.size()).append(" Valores contrato").toString());
//            int anterior = 0;
            do {
                if (!i.hasNext()) {
                    break;
                }
                PosicionAccion posicion = (PosicionAccion) i.next();
                ig.finanzas.ProductoPK productoPK = posicion.getProductoPK();
                if (!relacionProductosFactores.containsKey(productoPK)) {
                    generarHTML.println((new StringBuilder()).append("Falta definir el factor de riesgo para el producto ").append(productoPK).toString());
                    throw new LogicaExcepcion((new StringBuilder()).append("Falta definir el factor de riesgo para el producto ").append(productoPK).toString());
                }
                FactorRiesgoPersonalMetrica factor = (FactorRiesgoPersonalMetrica) relacionProductosFactores.get(productoPK);
                double var = posicion.valorEnRiesgo(fecha, factor, false);
                String factorMatriz = factor.getFactorRiesgoMatrizCorrelacion().getNombre();
                Double cambioesperado = 0.0D;
                if (factor.getTipoCalculoCambioEsperado() == FactorRiesgoPersonal.CAMBIOESPERADO_FACTORMATRIZ) {
                    cambioesperado = factor.getFactorRiesgoMatrizCorrelacion().getCambioEsperado();
                } else {
                    try {
                        cambioesperado = posicion.cambioEsperadoValoresRegistrados(fecha, factor.getDefinidorCalculoCambioEsperado(), false);
                    } catch (Exception e) {
                        cambioesperado = null;
                        generarHTML.println(" Error: Factor:" + factor.getFactorRiesgoMatrizCorrelacion().getNombre());
                        generarHTML.println(" Posiciones Acciones:" + e.toString());
                    }
                }
                if (cambioesperado != null) {
                    pstmt1.setLong(1, ((ContratoPK) posicion.getPrimaryKey()).getIdInterna());//varcontratosprecio
                    pstmt1.setDouble(2, var);
                    pstmt1.setString(3, factorMatriz);
                    pstmt1.setDouble(4, cambioesperado);
                    pstmt1.executeUpdate();
                }
                Moneda moneda = getMoneda(posicion.getMonedaPK());
                MonedaPK monedaPK = (MonedaPK) moneda.getPrimaryKey();
                if (!cambioesperadoMonedas.containsKey(monedaPK)) {
                    if (!relacionMonedasFactores.containsKey(monedaPK)) {
                        generarHTML.println((new StringBuilder()).append("Falta definir el factor de riesgo para la moneda ").append(monedaPK).toString());
                        throw new LogicaExcepcion((new StringBuilder()).append("Falta definir el factor de riesgo para la moneda ").append(monedaPK).toString());
                    }
                    FactorRiesgoPersonalMetrica factorMoneda = (FactorRiesgoPersonalMetrica) relacionMonedasFactores.get(monedaPK);
                    Double cambioesperadoMoneda = 0.0D;
                    Double ValorMonedaVigente = moneda.obtenerValorVigenteA(fecha);
                    if (factorMoneda.getTipoCalculoCambioEsperado() == FactorRiesgoPersonal.CAMBIOESPERADO_FACTORMATRIZ) {
                        cambioesperadoMoneda = factorMoneda.getFactorRiesgoMatrizCorrelacion().getCambioEsperado() * ValorMonedaVigente;
                    } else {
                        try {
                            cambioesperadoMoneda = moneda.cambioEsperadoValoresRegistrados(fecha, factorMoneda.getDefinidorCalculoCambioEsperado());
                            cambioesperadoMoneda = cambioesperadoMoneda * ValorMonedaVigente;
                        } catch (Exception e) {
                            cambioesperadoMoneda = null;
                            generarHTML.println(" Factor:" + factorMoneda.getFactorRiesgoMatrizCorrelacion().getNombre());
                            generarHTML.println(" Monedas:" + e.toString());
                        }
                    }
                    if (cambioesperadoMoneda != null) {
                        cambioesperadoMonedas.put(monedaPK, new Double(cambioesperadoMoneda));
                    }
                }
            } while (true);

        } catch (Exception e) {
            e.printStackTrace();
            throw new DatoInvalidoExcepcion(e.toString());
        }
    }

    public void efectuarCalculoContratosSimples(
            Date fecha,            
            Hashtable relacionProductosFactores,
            Hashtable relacionEspeciesFactores,
            Hashtable relacionMonedasFactores, 
            ManejadorBandas bandas)
            throws DatoInvalidoExcepcion, LogicaExcepcion, NamingException, SQLException, FinderException  {
        try {
            InitialContext ctx_ = new InitialContext(prop);
            ContratoSimpleHome home1 = (ContratoSimpleHome) ctx_.lookup("ig.finanzas.ContratoSimple");
            Collection contratos = home1.findAll();
            Iterator i = contratos.iterator();
            Productos productos = new Productos();
            //generarHTML.println((new StringBuilder()).append("Procesando :").append(contratos.size()).append(" Productos").toString());
            do {
                if (!i.hasNext()) {
                    break;
                }
                ContratoSimple contrato = (ContratoSimple) i.next();
                long idContrato = ((ContratoPK) contrato.getPrimaryKey()).getIdInterna();
                //Contratos contratoActual = new DaoTasasdepagos().loadById(idContrato);
                //contratoActual.getFormaCalculo()
                //if(contratoActual.getFormaCalculo().equals(1))//fija
                ig.finanzas.ProductoPK productoPK = productos.getProductoPK(Long.parseLong(contrato.getPrimaryKey().toString()));
                if (productoPK != null) {
                    ManejadorFlujos flujosduracion = contrato.flujosParaDuracion(fecha);
                    if (!relacionProductosFactores.containsKey(productoPK)) {
                        generarHTML.println((new StringBuilder()).append("Falta definir el factor de riesgo para el producto ").append(productoPK).toString());
                        throw new LogicaExcepcion((new StringBuilder()).append("Falta definir el factor de riesgo para el producto ").append(productoPK).toString());
                    } 
                    FactorRiesgoPersonalMetrica factor = (FactorRiesgoPersonalMetrica) relacionProductosFactores.get(productoPK);
                    TasaPK tasaPK = factor.getTasaPK();
                    if (tasaPK == null) {
                        generarHTML.println("El factor de riesgo asociado al producto no es del tipo tasa");
                        throw new DatoInvalidoExcepcion("El factor de riesgo asociado al producto no es del tipo tasa");
                    }
                    String factorMatriz = factor.getFactorRiesgoMatrizCorrelacion().getNombre();

                    Tasa tasa = null;
                    if (tasaPK.getNombre() != null && tasaPK.getNombre().trim().equals("TIPO_FACTORTASA_DESCUENTO")) {
                        tasa = new TasaFactorDescuento("TIPO_FACTORTASA_DESCUENTO", "CONTRATOSSIMPLES", ((IGLlaveInt) contrato.getPrimaryKey()).getIdInterna(), false);
                        ((TasaFactorDescuento) tasa).setTipo(tasa.TIPO_SIMPLE);
                    } else {
                        tasa = getTasa(tasaPK);
                    }

                    double cambioesperadoTasa;

                    if (factor.getTipoCalculoCambioEsperado() == FactorRiesgoPersonal.CAMBIOESPERADO_FACTORMATRIZ) {//is factor
                        cambioesperadoTasa = factor.getFactorRiesgoMatrizCorrelacion().getCambioEsperado();
//                        cambioesperadoTasa = Math.pow(1.0D + cambioesperadoTasa / 10000D, 0.083333332999999996D) - 1.0D;
                        cambioesperadoTasa = cambioesperadoTasa / 10000D;
                    } else {
                        cambioesperadoTasa = tasa.cambioEsperadoValoresRegistrados(fecha, factor.getDefinidorCalculoCambioEsperado());
//                        cambioesperadoTasa = Math.pow(1.0D + cambioesperadoTasa / 10000D, 0.083333332999999996D) - 1.0D;
                    }

                    Collection<VarContratosTasaDTO> varContratosTasaDTOs = new ArrayList<VarContratosTasaDTO>();
                    for (Iterator j = bandas.getColeccionBandas().iterator(); j.hasNext();) {
                        Banda banda = (Banda) j.next();
                        ManejadorFlujos flujosintervalo = flujosduracion.flujosEntre(banda.getFechaInicio(), false, banda.getFechaFin(), true);
                        //saldo contable de contratos                        
                        double valorpresente = 0D;
                        /*if(((ContratoPK) contrato.getPrimaryKey()).getIdInterna()==1001054 ){
                            System.out.println("Este es:"+((ContratoPK) contrato.getPrimaryKey()).getIdInterna());
                        }*/
                        //carga TASA_DESCUENTO de contratosimple
                        if (!(tasa instanceof TasaFactorDescuento)) {
                            valorpresente = flujosintervalo.valorDescontado(tasa, fecha);
                        }else{
                            double TS = ((TasaFactorDescuento) tasa).obtenerValorVigenteANormal();
                            if (TS == 0) {
                                ((TasaFactorDescuento) tasa).setFuente("CONTRATOS");
                                ((TasaFactorDescuento) tasa).setCampo("SALDOCONTABLE");
                                valorpresente = ((TasaFactorDescuento) tasa).obtenerValorVigenteANormal();
                                ((TasaFactorDescuento) tasa).setFuente("CONTRATOSSIMPLES");
                                ((TasaFactorDescuento) tasa).setCampo("TASA_DESCUENTO");
                            } else {
                                valorpresente = flujosintervalo.valorDescontado(tasa, fecha);
                            }                            
                        }
                        double duracion = flujosintervalo.duracion(fecha, tasa);
                        flujosintervalo.adicionarFlujo(new Flujo(fecha, valorpresente * -1D, 0.0D, 0.0D, false, false));
                        double tir = flujosintervalo.tir();
                        if (tir < 0.0D) {
                            System.out.println("La Tir es negativa :" + tir + " para el contrato " + contrato.getPrimaryKey());
                            tir = 0.0D;
                        }
                        Double var = 0D;
                        double exposicion = ((valorpresente * duracion) / (1.0D + tir));
                        varContratosTasaDTOs.add(new VarContratosTasaDTO(((ContratoPK) contrato.getPrimaryKey()).getIdInterna(), valorpresente, duracion, tir, cambioesperadoTasa, var, factorMatriz, banda.getIdInterna(), exposicion));
                    }

                    /* busco la moneda asiganada */
                    Moneda moneda = getMoneda(contrato.getMonedaPK());
                    MonedaPK monedaPK = (MonedaPK) moneda.getPrimaryKey();
                    if (!cambioesperadoMonedas.containsKey(monedaPK)) {
                        if (!relacionMonedasFactores.containsKey(monedaPK)) {
                            generarHTML.println((new StringBuilder()).append("Falta definir el factor de riesgo para la moneda ").append(monedaPK).toString());
                            throw new LogicaExcepcion((new StringBuilder()).append("Falta definir el factor de riesgo para la moneda ").append(monedaPK).toString());
                        }
                        FactorRiesgoPersonalMetrica factorMoneda = (FactorRiesgoPersonalMetrica) relacionMonedasFactores.get(monedaPK);
                        double cambioesperadoMoneda = 0.0D;
                        Double ValorMonedaVigente = moneda.obtenerValorVigenteA(fecha);
                        if (factorMoneda.getTipoCalculoCambioEsperado() == FactorRiesgoPersonal.CAMBIOESPERADO_FACTORMATRIZ) {
                            cambioesperadoMoneda = factorMoneda.getFactorRiesgoMatrizCorrelacion().getCambioEsperado() * ValorMonedaVigente;
                        } else {
                            cambioesperadoMoneda = moneda.cambioEsperadoValoresRegistrados(fecha, factorMoneda.getDefinidorCalculoCambioEsperado());
                            cambioesperadoMoneda = cambioesperadoMoneda * ValorMonedaVigente;
                        }
                        cambioesperadoMonedas.put(monedaPK, new Double(cambioesperadoMoneda));
                    }
                    Integer ZonaQueJuega = null;
                    if (moneda.getNombre().toUpperCase().trim().equals("PESO") || moneda.getNombre().toUpperCase().trim().equals("PESOS")) {
                        ZonaQueJuega = 1;
                    } else if (moneda.getNombre().toUpperCase().trim().equals("UVR")) {
                        ZonaQueJuega = 2;
                    } else {
                        ZonaQueJuega = 3;
                    }

                    Double[] VER = this.evaluarBanda(" del Producto " + productoPK.toString().trim(), varContratosTasaDTOs, ZonaQueJuega);

                    pstmt4.setDouble(1, VER[0]);
                    pstmt4.setDouble(2, VER[1]);
                    pstmt4.setDouble(3, VER[2]);
                    pstmt4.setLong(4, idContrato);
                    pstmt4.executeUpdate();
                    pstmt4.clearParameters();
                    for (VarContratosTasaDTO varContratosTasaDTO : varContratosTasaDTOs) {
                        pstmt2.setLong(1, varContratosTasaDTO.getIdContrato());
                        pstmt2.setDouble(2, varContratosTasaDTO.getValorpresente());
                        pstmt2.setDouble(3, varContratosTasaDTO.getDuracion());
                        pstmt2.setDouble(4, varContratosTasaDTO.getTir());
                        pstmt2.setDouble(5, varContratosTasaDTO.getCambioesperadoTasa());
                        pstmt2.setDouble(6, varContratosTasaDTO.getVer());
                        pstmt2.setString(7, varContratosTasaDTO.getFactorMatriz());
                        pstmt2.setLong(8, varContratosTasaDTO.getIdBanda());
                        pstmt2.setDouble(9, varContratosTasaDTO.getExposicion());
                        if (varContratosTasaDTO.getVarPrincipar1() != null) {
                            pstmt2.setDouble(10, varContratosTasaDTO.getVarPrincipar1());
                        } else {
                            pstmt2.setNull(10, java.sql.Types.NULL);
                        }
                        if (varContratosTasaDTO.getVarPrincipar2() != null) {
                            pstmt2.setDouble(11, varContratosTasaDTO.getVarPrincipar2());
                        } else {
                            pstmt2.setNull(11, java.sql.Types.NULL);
                        }
                        if (varContratosTasaDTO.getVarPrincipar3() != null) {
                            pstmt2.setDouble(12, varContratosTasaDTO.getVarPrincipar3());
                        } else {
                            pstmt2.setNull(12, java.sql.Types.NULL);
                        }
                        pstmt2.executeUpdate();
                        pstmt2.clearParameters();
                    }
                }
            } while (true);
            productos.Finalizar();
        } catch (Exception e) {
            e.printStackTrace();
            throw new DatoInvalidoExcepcion(e.toString());
        }
    }

    public void efectuarCalculoPosicionesEspecies(
            Date fecha,
            Hashtable relacionProductosFactores,
            Hashtable relacionEspeciesFactores,
            Hashtable relacionMonedasFactores, 
            ManejadorBandas bandas)

            throws DatoInvalidoExcepcion, LogicaExcepcion, NamingException, SQLException, FinderException {
        try {
            InitialContext ctx_ = new InitialContext(prop);

            PosicionEspecieHome home2 = (PosicionEspecieHome) ctx_.lookup("ig.finanzas.PosicionEspecie");
            Collection contratos = home2.findAll();
            Iterator i = contratos.iterator();
            //generarHTML.println((new StringBuilder()).append("Procesando :").append(contratos.size()).append(" Contratos").toString());
            //generarHTML.println("Procesando :Factores de riesgo");
            do {
                if (!i.hasNext()) {
                    break;
                }
                PosicionEspecie posicion = (PosicionEspecie) i.next();
                long idContrato = ((ContratoPK) posicion.getPrimaryKey()).getIdInterna();
                EspeciePK especiePK = posicion.getEspeciePK();
                if (!relacionEspeciesFactores.containsKey(especiePK)) {
                    generarHTML.println((new StringBuilder()).append("Falta definir el factor de riesgo para la especie ").append(especiePK.toString()).toString());
                    throw new LogicaExcepcion((new StringBuilder()).append("Falta definir el factor de riesgo para la especie ").append(especiePK.toString()).toString());
                }
                FactorRiesgoPersonalMetrica factor = (FactorRiesgoPersonalMetrica) relacionEspeciesFactores.get(especiePK);

                Moneda moneda = getMoneda(posicion.getMonedaPK());
                MonedaPK monedaPK = (MonedaPK) moneda.getPrimaryKey();
                if (!cambioesperadoMonedas.containsKey(monedaPK)) {
                    if (!relacionMonedasFactores.containsKey(monedaPK)) {
                        generarHTML.println((new StringBuilder()).append("Falta definir el factor de riesgo para la moneda ").append(monedaPK).toString());
                        throw new LogicaExcepcion((new StringBuilder()).append("Falta definir el factor de riesgo para la moneda ").append(monedaPK).toString());
                    }
                    FactorRiesgoPersonalMetrica factorMoneda = (FactorRiesgoPersonalMetrica) relacionMonedasFactores.get(monedaPK);
                    double cambioesperadoMoneda = 0.0D;
                    Double ValorMonedaVigente = moneda.obtenerValorVigenteA(fecha);
                    if (factorMoneda.getTipoCalculoCambioEsperado() == FactorRiesgoPersonal.CAMBIOESPERADO_FACTORMATRIZ) {
                        cambioesperadoMoneda = factorMoneda.getFactorRiesgoMatrizCorrelacion().getCambioEsperado() * ValorMonedaVigente;
                    } else {
                        cambioesperadoMoneda = moneda.cambioEsperadoValoresRegistrados(fecha, factorMoneda.getDefinidorCalculoCambioEsperado());
                        cambioesperadoMoneda = cambioesperadoMoneda * ValorMonedaVigente;
                    }
                    cambioesperadoMonedas.put(monedaPK, new Double(cambioesperadoMoneda));
                }

                //TIPO_FACTORPRECIO = 0;
                //TIPO_FACTORTASA = 1;
                //TIPO_FACTORTASA_DESCUENTO = 2;

                if (factor.getTipo() == FactorRiesgoPersonal.TIPO_FACTORPRECIO) {
                    double var = posicion.valorEnRiesgo(fecha, factor, true) * 100;

                    String factorMatriz = factor.getFactorRiesgoMatrizCorrelacion().getNombre();
                    double cambioesperado = 0.0D;
                    if (factor.getTipoCalculoCambioEsperado() == FactorRiesgoPersonal.CAMBIOESPERADO_FACTORMATRIZ) {
                        cambioesperado = factor.getFactorRiesgoMatrizCorrelacion().getCambioEsperado();
                    } else {
                        cambioesperado = posicion.cambioEsperadoValoresRegistrados(fecha, factor.getDefinidorCalculoCambioEsperado(), true);
                    }
                    pstmt1.setLong(1, ((ContratoPK) posicion.getPrimaryKey()).getIdInterna());
                    pstmt1.setDouble(2, Math.round(var * 100D) / 100L);
                    pstmt1.setString(3, factorMatriz);
                    pstmt1.setDouble(4, (double) Math.round(cambioesperado * 100000000D) / 100000000D);
                    pstmt1.executeUpdate();
                } else {
                    Collection<VarContratosTasaDTO> varContratosTasaDTOs = new ArrayList<VarContratosTasaDTO>();
                    ManejadorFlujos flujosduracion = posicion.flujosParaDuracion(fecha);

                    TasaPK tasaPK = factor.getTasaPK();
                    Tasa tasa = null;

                    if (tasaPK.getNombre() != null && tasaPK.getNombre().trim().equals("TIPO_FACTORTASA_DESCUENTO")) {
                        tasa = new TasaFactorDescuento("TIPO_FACTORTASA_DESCUENTO", "POSICIONESESPECIES", ((IGLlaveInt) posicion.getPrimaryKey()).getIdInterna(), true);
                        ((TasaFactorDescuento) tasa).setTipo(tasa.TIPO_SIMPLE);
                    } else {
                        tasa = getTasa(tasaPK);
                    }
                    if (tasaPK == null) {
                        generarHTML.println("El factor de riesgo asociado al producto no es del tipo tasa");
                        throw new DatoInvalidoExcepcion("El factor de riesgo asociado al producto no es del tipo tasa");
                    }

                    /***
                     * Es la validación par el DTF
                     */
                    String factorMatriz = factor.getFactorRiesgoMatrizCorrelacion().getNombre();

                    //if CC PESOS ||  CC UVR || CC TESOROS
                    ///if (tasa.getTipo() != null && tasa.getTipo().equals(tasa.TIPO_CURVA)) {//calculo con matriz de choques
                    if (factorMatriz.startsWith("CC PESOS") || factorMatriz.startsWith("CC UVR") || factorMatriz.startsWith("CC TESORO")) {//calculo con matriz de choques

                        double cambioesperadoTasa;
                        if (factor.getTipoCalculoCambioEsperado() == FactorRiesgoPersonal.CAMBIOESPERADO_FACTORMATRIZ) {
                            cambioesperadoTasa = factor.getFactorRiesgoMatrizCorrelacion().getCambioEsperado();
                            cambioesperadoTasa = cambioesperadoTasa / 10000D;
                        } else {
                            cambioesperadoTasa = tasa.cambioEsperadoValoresRegistrados(fecha, factor.getDefinidorCalculoCambioEsperado());
                        }

                        for (Iterator j = bandas.getColeccionBandas().iterator(); j.hasNext(); /*pstmt2.executeUpdate()*/) {
                            Banda banda = (Banda) j.next();
                            ManejadorFlujos flujosintervalo = flujosduracion.flujosEntre(banda.getFechaInicio(), false, banda.getFechaFin(), true);
                            double valorpresente = flujosintervalo.valorDescontado(tasa, fecha);
                            double duracion = flujosintervalo.duracion(fecha, tasa);
                            //flujosintervalo.adicionarFlujo(new Flujo(fecha, valorpresente * -1D, 0.0D, 0.0D, false, false));
                            //double tir = flujosintervalo.tir();
                            //Cambio realizado por Cristhiam
                            double tir;

                            double var = 0D;//valorpresente * (duracion / (1.0D + tir)) * cambioesperadoTasa;
                            //double exposicion = ((valorpresente * duracion) / /*Math.pow(*/ (1.0D + tir)/*,duracion)*/);

                            //double exposicion = ((valorpresente * duracion) / /*Math.pow(*/ (1.0D + tir)/*,duracion)*/);
                            /*
                             * Cambio Creado por Cristhiam Reina
                             * Cambio Creado el 18/07/2011
                             */
                            double exposicion = 0;

                            if(tasa.getTipo().equals(tasa.TIPO_SIMPLE))
                            {
                                flujosintervalo.adicionarFlujo(new Flujo(fecha, valorpresente * -1D, 0.0D, 0.0D, false, false));
                                tir = flujosintervalo.tir();
                                exposicion = ((valorpresente * duracion) / /*Math.pow(*/ (1.0D + tir)/*,duracion)*/);
                            }
                            else
                            {
                                exposicion = flujosintervalo.expocision(fecha, tasa);
                                flujosintervalo.adicionarFlujo(new Flujo(fecha, valorpresente * -1D, 0.0D, 0.0D, false, false));
                                tir = flujosintervalo.tir();
                            }
                            valorpresente = Math.round(valorpresente * 100D) / 100L;
                            duracion = (double) Math.round(duracion * 10000D) / 10000D;
                            //tir = (double) Math.round(tir * 100000000D) / 100000000D;//TirOfFlujo.
                            cambioesperadoTasa = (double) Math.round(cambioesperadoTasa * 100000000D) / 100000000D;
                            //var = Math.round(var * 100D) / 100L;
                            //var = 0D;
                            varContratosTasaDTOs.add(new VarContratosTasaDTO(((ContratoPK) posicion.getPrimaryKey()).getIdInterna(), valorpresente, duracion, tir, cambioesperadoTasa, var, factorMatriz, banda.getIdInterna(), exposicion));
                        }

                        Integer ZonaQueJuega = null;
                        if (moneda.getNombre().toUpperCase().trim().equals("PESO") || moneda.getNombre().toUpperCase().trim().equals("PESOS") || moneda.getNombre().toUpperCase().trim().equals("COP")) {
                            ZonaQueJuega = 1;
                        } else if (moneda.getNombre().toUpperCase().trim().equals("UVR")) {
                            ZonaQueJuega = 2;
                        } else {
                            ZonaQueJuega = 3;
                        }
                        Double[] VER = this.evaluarBanda(" de la Especie " + posicion.getEspeciePK().toString().trim(), varContratosTasaDTOs, ZonaQueJuega);

                        pstmt4.setDouble(1, VER[0]);
                        pstmt4.setDouble(2, VER[1]);
                        pstmt4.setDouble(3, VER[2]);
                        pstmt4.setLong(4, idContrato);
                        pstmt4.executeUpdate();
                        pstmt4.clearParameters();

                    } else { //if (tasa.getTipo() == null || tasa.getTipo().equals(tasa.TIPO_SIMPLE)) { //varible
                        try {
                            if (factor.getFactorRiesgoMatrizCorrelacion().getNombre().startsWith("DTF ")) {
                                Iterator j = bandas.getColeccionBandas().iterator();
                                if (j.hasNext()) {
                                    String FACTOR = null;
                                    Banda banda = (Banda) j.next();
                                    ManejadorFlujos flujosintervalo = flujosduracion.flujosEntre(banda.getFechaInicio(), false, new Date(java.sql.Timestamp.valueOf("9999-12-31 00:00:00").getTime()), true);
                                    Long dias = null;
                                    try {
                                        dias = (flujosintervalo.fechaUltimoFlujo().getTime() - fecha.getTime()) / (1000 * 60 * 60 * 24);
                                    } catch (DatoInvalidoExcepcion e) {
                                        throw new DatoInvalidoExcepcion("No existen Flujos para el contrato "+ ((ContratoPK) posicion.getPrimaryKey()).getIdInterna()+", en las fechas :" + banda.getFechaFin() + " - 9999-12-31 00:00:00" );
                                    }
                                    if (dias > 365) {
                                        FACTOR = "DTF LP";
                                    } else {
                                        FACTOR = "DTF CP";
                                    }
                                    for (Object elem : factores) {
                                        if (((FactorRiesgoMatrizCorrelacion) elem).getNombre().trim().equals(FACTOR)) {
                                            factor.setFactorRiesgoMatrizCorrelacion(((FactorRiesgoMatrizCorrelacion) elem));
                                            factorMatriz = ((FactorRiesgoMatrizCorrelacion) elem).getNombre();
                                            break;
                                        }
                                    }
                                }
                            }

                            double cambioesperadoTasa;
                            if (factor.getTipoCalculoCambioEsperado() == FactorRiesgoPersonal.CAMBIOESPERADO_FACTORMATRIZ) {
                                cambioesperadoTasa = factor.getFactorRiesgoMatrizCorrelacion().getCambioEsperado();
                                //cambioesperadoTasa = cambioesperadoTasa / 10000D;
                            } else {
                                cambioesperadoTasa = tasa.cambioEsperadoValoresRegistrados(fecha, factor.getDefinidorCalculoCambioEsperado());
                            }
                            //desarrollo deferente

                            Iterator j = bandas.getColeccionBandas().iterator();
                            if (j.hasNext()) {
                                Banda banda = (Banda) j.next();
                                ManejadorFlujos flujosintervalo = flujosduracion.flujosEntre(banda.getFechaInicio(), false, new Date(java.sql.Timestamp.valueOf("9999-12-31 00:00:00").getTime()), true);
                                double valorpresente = flujosintervalo.valorDescontado(tasa, fecha);
                                double duracion = flujosintervalo.duracion(fecha, tasa);
                                flujosintervalo.adicionarFlujo(new Flujo(fecha, valorpresente * -1D, 0.0D, 0.0D, false, false));
                                double tir = flujosintervalo.tir();
                                //double var = valorpresente * (duracion / (1.0D + tir)) * cambioesperadoTasa;
                                //valorpresente = posicion.getSaldoContable();
                                //double var = valorpresente * (duracion / (1.0D + tir)) * cambioesperadoTasa;
                                valorpresente = Math.round(valorpresente * 100D) / 100L;
                                duracion = (double) Math.round(duracion * 10000D) / 10000D;
                                tir = (double) Math.round(tir * 100000000D) / 100000000D;
                                cambioesperadoTasa = (double) Math.round(cambioesperadoTasa * 100000000D) / 100000000D;
                                //var = Math.round(var * 100D) / 100L;
                                //var = 0D;
                                double exposicion = ((valorpresente * duracion) / /*Math.pow(*/ (1.0D + tir)/*,duracion)*/);
                                double var = exposicion * cambioesperadoTasa;
                                varContratosTasaDTOs.add(new VarContratosTasaDTO(((ContratoPK) posicion.getPrimaryKey()).getIdInterna(), valorpresente, duracion, tir, cambioesperadoTasa, var, factorMatriz, banda.getIdInterna(), exposicion));
                            }
                        } catch (DatoInvalidoExcepcion ex) {
                            generarHTML.println("Error : " + ex.getMessage());
                        }
                    }
                    for (VarContratosTasaDTO varContratosTasaDTO : varContratosTasaDTOs) {
                        pstmt2.setLong(1, varContratosTasaDTO.getIdContrato());
                        pstmt2.setDouble(2, varContratosTasaDTO.getValorpresente());
                        pstmt2.setDouble(3, varContratosTasaDTO.getDuracion());
                        pstmt2.setDouble(4, varContratosTasaDTO.getTir());
                        pstmt2.setDouble(5, varContratosTasaDTO.getCambioesperadoTasa());
                        pstmt2.setDouble(6, varContratosTasaDTO.getVer());
                        pstmt2.setString(7, varContratosTasaDTO.getFactorMatriz());
                        pstmt2.setLong(8, varContratosTasaDTO.getIdBanda());
                        pstmt2.setDouble(9, varContratosTasaDTO.getExposicion());

                        if (varContratosTasaDTO.getVarPrincipar1() != null) {
                            pstmt2.setDouble(10, varContratosTasaDTO.getVarPrincipar1());
                        } else {
                            pstmt2.setNull(10, java.sql.Types.NULL);
                        }

                        if (varContratosTasaDTO.getVarPrincipar2() != null) {
                            pstmt2.setDouble(11, varContratosTasaDTO.getVarPrincipar2());
                        } else {
                            pstmt2.setNull(11, java.sql.Types.NULL);
                        }

                        if (varContratosTasaDTO.getVarPrincipar3() != null) {
                            pstmt2.setDouble(12, varContratosTasaDTO.getVarPrincipar3());
                        } else {
                            pstmt2.setNull(12, java.sql.Types.NULL);
                        }
                        pstmt2.executeUpdate();
                        pstmt2.clearParameters();
                    }
                }
            } while (true);
        } catch (Exception e) {
            e.printStackTrace();
            throw new DatoInvalidoExcepcion(e.toString());
        }

    }

    private Double[] evaluarBanda(String entidad, Collection<VarContratosTasaDTO> varContratosTasaDTOs, Integer ZonaQueJuega) throws LogicaExcepcion, RemoteException, Exception {
        Double[] VER = {0D, 0D, 0D};
        /*Calculo de los 3 vares*/
        if (this.collection != null && this.collection.size()>0) {
            for (VarContratosTasaDTO varContratosTasaDTO : varContratosTasaDTOs) {
                Integer IDBanda = null;
                for (ZonaDTO Z : this.collection) {
                    if (ZonaQueJuega.equals(Z.getNumero())) {
                        for (BandasDTO B : Z.getBandas()) {
                            IDBanda = null;
                            if (varContratosTasaDTO.getIdBanda().equals(B.getNumero())) {
                                //if ((varContratosTasaDTO.getDuracion() * 365) >= B.getLimiteInferior() && (varContratosTasaDTO.getDuracion() * 365) < B.getLimiteSuperior()) {
                                int fac = 0;
                                for (FactorRiesgoMatrizCorrelacionMetrica F : B.getCollection()) {
                                    if (fac == 0) {
                                        varContratosTasaDTO.setVarPrincipar1(varContratosTasaDTO.getExposicion() * F.getCambioEsperadoPBS().getCambioEsperado());
                                    } else if (fac == 1) {
                                        varContratosTasaDTO.setVarPrincipar2(varContratosTasaDTO.getExposicion() * F.getCambioEsperadoPBS().getCambioEsperado());
                                    } else if (fac == 2) {
                                        varContratosTasaDTO.setVarPrincipar3(varContratosTasaDTO.getExposicion() * F.getCambioEsperadoPBS().getCambioEsperado());
                                    }
                                    VER[fac++] += varContratosTasaDTO.getExposicion() * F.getCambioEsperadoPBS().getCambioEsperado();
                                }
                                IDBanda = B.getNumero();
                            }
                            if (IDBanda != null) {
                                break;
                            }
                        }//for Bandas
                    }//for ZonaQueJuega
                    if (IDBanda != null) {
                        break;
                    }
                }//for Zonas
                if (IDBanda == null) {
                    throw new LogicaExcepcion("la duracion " + varContratosTasaDTO.getDuracion() + entidad + " no cae en ninguna banda");
                }
            }
        }

        return VER;

    }

    public void setZonas(Collection<ZonaDTO> collection) {
        this.collection = collection;
    }

    public boolean isFechaInicioCerrada() {
        return fechaInicioCerrada;
    }

    public void setFechaInicioCerrada(boolean fechaInicioCerrada) {
        this.fechaInicioCerrada = fechaInicioCerrada;
    }

    public void setFactores(Object get) {
        this.factores = (Collection) get;
    }

    private void _printHT(Hashtable ht, String name) {
        System.out.println("*******************");
        System.out.println("Name:" + name);
        Enumeration Key = ht.keys();
        while (Key.hasMoreElements()) {
            Object key = Key.nextElement();
            try {
                ig.metrica.riesgo.FactorRiesgoPersonalMetrica FACTOR = ((ig.metrica.riesgo.FactorRiesgoPersonalMetrica) ht.get(key));
                Byte TIPO = FACTOR.getTipo();
                String TASAPK = null;
                if (FACTOR.getTasaPK() != null) {
                    TASAPK = FACTOR.getTasaPK().toString();
                }
                Byte TIPO_CAL_ESP = FACTOR.getTipoCalculoCambioEsperado();
                String FACTOR_MATRIZ = FACTOR.getFactorRiesgoMatrizCorrelacion().getNombre();

                System.out.println(key.toString().trim() + "=TIPO:" + TIPO + ",TASAPK:" + TASAPK + ",TIPO_CAL_ESP:" + TIPO_CAL_ESP + ",FACTOR_MATRIZ:" + FACTOR_MATRIZ);
            } catch (Exception e) {
                String DATO = ((String) ht.get(key));
                System.out.println("DATO:" + DATO);
            }
        }
        System.out.println("*");
    }
}

